﻿/*----------------------------------------------------------------

// 公司名称：公司名称
//
// 产品名称：Gaf
//
// 创 建 人：netcasewqs
// 创建日期：2022/3/4
// 邮    箱：netcasewqs@qq.com
//
// Copyright (C) 2022 Gaf，保留所有权利。
//
//----------------------------------------------------------------*/

namespace Gaf.Impl;

internal interface IConfigurationMethodInvoker
{
    void InvokdeConfigureMethod(object instance, IServiceCollection? services, IConfiguration? configuration);
}

record ConfigurationMethodInvoker : IConfigurationMethodInvoker
{
    private static readonly Type _serviceType = typeof(IServiceCollection).GetTypeInfo();
    private static readonly Type _configurationType = typeof(IConfiguration).GetTypeInfo();

    public MethodInfo Method { get; }
    public ParameterInfo[] Parameters { get; }

    public ConfigurationMethodInvoker(MethodInfo method, params ParameterInfo[] parameters)
    {
        this.Method = method;
        this.Parameters = parameters;
    }

    public void InvokdeConfigureMethod(object instance, IServiceCollection? services, IConfiguration? configuration)
    {
        try
        {
            //多参数
            var args = new object[Parameters.Length];

            StringBuilder? errorMessage = default;

            for (int i = 0; i < Parameters.Length; i++)
            {
                var parameterType = Parameters[i].ParameterType;
                if (_serviceType == parameterType) args[i] = services!;
                else if (_configurationType == parameterType) args[i] = configuration!;
                else
                {
                    var serviceDescriptor = services?.FirstOrDefault(p => p.ServiceType == parameterType);
                    if (serviceDescriptor == null)
                    {
                        if (errorMessage == null) errorMessage = new StringBuilder(200);
                        errorMessage.Append($"{parameterType.Namespace}.{parameterType.Name} 服务没注册");
                    }
                    else
                    {
                        if (serviceDescriptor.ImplementationInstance != null) args[i] = serviceDescriptor.ImplementationInstance;
                        else
                        {
                            using var provider = services!.BuildServiceProvider();
                            using var scope = provider.CreateScope();
                            var arg = scope.ServiceProvider.GetService(parameterType);
                            if (arg == null)
                            {
                                if (errorMessage == null) errorMessage = new StringBuilder(200);
                                errorMessage.Append($"{parameterType.Namespace}.{parameterType.Name} 服务没注册");
                            }
                            else
                            {
                                args[i] = arg;
                            }
                        }
                    }
                }
            }
            if (errorMessage != null)
            {
                var instanceType = instance.GetType().GetTypeInfo();
                throw new InvalidOperationException($"调用 {instanceType.Namespace}.{instanceType.Name}.{Method.Name} 出错,详细信息:{errorMessage}");
            }

            Method.Invoke(Method.IsStatic ? null : instance, args);
        }
        catch (TargetInvocationException ex)
        {
            throw ex.InnerException!;
        }
    }
}